/**
 * @file Logger.cpp
 * @brief 日志记录器实现
 * @author Enterprise Logger Team
 * @date 2024
 */

#include "Logger.h"
#include <cinttypes>
#include <iostream>
#include <sstream>
#include <thread>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <functional>

namespace logger {

// 全局变量定义
std::atomic<logger::LogLevel> g_logLevel{logger::LogLevel::INFO_LEVEL};

// 日志级别名称
const char* LogLevelName[static_cast<int>(logger::LogLevel::NUM_LOG_LEVELS)] = {
    "TRACE ",
    "DEBUG ",
    "INFO  ",
    "WARN  ",
    "ERROR ",
    "FATAL ",
};

// 默认输出函数（输出到标准输出）
void defaultOutput(const char* msg, int len)
{
    size_t n = fwrite(msg, 1, len, stdout);
    (void)n;   // 避免未使用警告
}

// 默认刷新函数
void defaultFlush()
{
    fflush(stdout);
}

// 全局输出和刷新函数
Logger::OutputFunc g_output = defaultOutput;
Logger::FlushFunc  g_flush  = defaultFlush;

// 线程局部存储：缓存时间字符串
thread_local time_t t_lastSecond = 0;
thread_local char   t_time[64]   = {0};

// Timestamp实现
std::string Timestamp::toString() const
{
    char    buf[32]      = {0};
    int64_t seconds      = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
    int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;
    snprintf(buf, sizeof(buf), "%" PRId64 ".%06" PRId64, seconds, microseconds);
    return buf;
}

std::string Timestamp::toFormattedString(bool showMicroseconds) const
{
    char    buf[128]     = {0};
    int64_t seconds      = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
    int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;

    // 转换为本地时间
    time_t    time_sec = static_cast<time_t>(seconds);
    struct tm tm_time;

#ifdef _WIN32
    localtime_s(&tm_time, &time_sec);
#else
    localtime_r(&time_sec, &tm_time);
#endif

    if (showMicroseconds) {
        int len = snprintf(buf,
                           sizeof(buf),
                           "%04d-%02d-%02d %02d:%02d:%02d.%06" PRId64,
                           tm_time.tm_year + 1900,
                           tm_time.tm_mon + 1,
                           tm_time.tm_mday,
                           tm_time.tm_hour,
                           tm_time.tm_min,
                           tm_time.tm_sec,
                           microseconds);
        (void)len;
    }
    else {
        int len = snprintf(buf,
                           sizeof(buf),
                           "%04d-%02d-%02d %02d:%02d:%02d",
                           tm_time.tm_year + 1900,
                           tm_time.tm_mon + 1,
                           tm_time.tm_mday,
                           tm_time.tm_hour,
                           tm_time.tm_min,
                           tm_time.tm_sec);
        (void)len;
    }

    return buf;
}

// Logger::Impl实现
Logger::Impl::Impl(LogLevel level, int old_errno, const SourceFile& file, int line)
    : time_(Timestamp::now())
    , stream_()
    , level_(level)
    , line_(line)
    , basename_(file)
{

    // 格式化时间
    formatTime();

    // 添加线程ID（简洁数字格式，类似你截图中的风格）
    std::hash<std::thread::id> hasher;
    size_t                     thread_hash = hasher(std::this_thread::get_id());
    uint32_t                   thread_id =
        static_cast<uint32_t>(thread_hash % 99999) + 1;   // 1-99999范围，更接近你截图的风格
    stream_ << " [T" << thread_id << "]";
    // 添加日志级别（对齐格式）
    stream_ << " " << LogLevelName[static_cast<int>(level)];

    // 如果有错误码，添加错误信息
    if (old_errno != 0) {
        stream_ << " " << strerror(old_errno) << " (errno=" << old_errno << ")";
    }
}

void Logger::Impl::formatTime()
{
    int64_t microSecondsSinceEpoch = time_.microSecondsSinceEpoch();
    time_t  seconds =
        static_cast<time_t>(microSecondsSinceEpoch / Timestamp::kMicroSecondsPerSecond);
    int microseconds = static_cast<int>(microSecondsSinceEpoch % Timestamp::kMicroSecondsPerSecond);

    // 使用线程局部存储优化：同一秒内复用时间字符串
    if (seconds != t_lastSecond) {
        t_lastSecond = seconds;
        struct tm tm_time;

#ifdef _WIN32
        localtime_s(&tm_time, &seconds);
#else
        localtime_r(&seconds, &tm_time);
#endif

        int len = snprintf(t_time,
                           sizeof(t_time),
                           "%04d-%02d-%02d %02d:%02d:%02d",
                           tm_time.tm_year + 1900,
                           tm_time.tm_mon + 1,
                           tm_time.tm_mday,
                           tm_time.tm_hour,
                           tm_time.tm_min,
                           tm_time.tm_sec);
        (void)len;
    }

    // 添加时间戳
    stream_ << t_time;

    // 添加毫秒（企业级标准：3位毫秒精度）
    char buf[32];
    int  milliseconds = microseconds / 1000;
    int  len          = snprintf(buf, sizeof(buf), ".%03d", milliseconds);
    stream_.append(buf, len);
}

void Logger::Impl::finish()
{
    stream_ << " - " << basename_.data_ << ":" << line_ << "\n";
}

// Logger构造函数
Logger::Logger(SourceFile file, int line)
    : impl_(logger::LogLevel::INFO_LEVEL, 0, file, line)
{}

Logger::Logger(SourceFile file, int line, LogLevel level)
    : impl_(level, 0, file, line)
{}

Logger::Logger(SourceFile file, int line, LogLevel level, const char* func)
    : impl_(level, 0, file, line)
{
    impl_.stream_ << func << ' ';
}

Logger::Logger(SourceFile file, int line, bool toAbort)
    : impl_(toAbort ? logger::LogLevel::FATAL_LEVEL : logger::LogLevel::ERROR_LEVEL, errno, file,
            line)
{}

// Logger析构函数
Logger::~Logger()
{
    impl_.finish();
    const LogStream::Buffer& buf(stream().buffer());
    g_output(buf.data(), buf.length());

    // FATAL级别退出程序
    if (impl_.level_ == logger::LogLevel::FATAL_LEVEL) {
        g_flush();
        abort();
    }
}

// 设置输出函数
void Logger::setOutput(OutputFunc out)
{
    g_output = out;
}

// 设置刷新函数
void Logger::setFlush(FlushFunc flush)
{
    g_flush = flush;
}

}   // namespace logger
